#pragma once

#include "FeatureBuilder.h"
#include "ChartBuilder.h"
#include "Timing.h"

namespace LSCM
{
	/**
	 * @file LSCMBuilder.h
	 * @author xingyifan
	 * @date 2023-08-18 17:49
	 * 
	 * @description: LSCM 构建器
	 */
	
	class LSCMBuilder
	{
	private:
		// 记录顶点状态
		struct VertexStates
		{
			bool fixed;
			int id;

			VertexStates(bool fixed = false, int id = -1) : fixed(fixed), id(id) {}
		};

		Mesh* m_mesh;
		FeatureMetric* m_metric;

		// 句柄，用于增加属性值
		OpenMesh::VPropHandleT<VertexStates> m_vertexStates;
		OpenMesh::FPropHandleT<int> m_faceId;

	public:
		LSCMBuilder(Mesh* mesh, FeatureMetric* metric = nullptr);
		~LSCMBuilder();

		std::vector<Chart> Build();

	private:
		Mesh::Point OBB(const VertexList& vertices);
		int initializeIndex(const Chart& chart);
		void initializeSystem(const Chart& chart, SparseMatrix& A, SparseMatrix& fA, MatrixXx1& fx);
		void projectFace(const Mesh::FaceHandle& face, Mesh::Point* pv, Mesh::VertexHandle* hv);
	};
} // namespace LSCM
